import type { RawAxiosRequestConfig, AxiosInstance, AxiosRequestConfig } from 'axios';

import { kaRequestConfig } from './type';
import axios from 'axios';

// 网络请求中的遮盖c

class kaRequest {
  instance: AxiosInstance;

  //创建axios实例

  constructor(config: kaRequestConfig) {
    this.instance = axios.create(config);
    //每个请求的拦截 全局拦截
    this.instance.interceptors.request.use(
      (config) => {
        return config;
      },
      (err) => err
    );

    this.instance.interceptors.response.use(
      (res) => {
        return res.data; // 让axios默认 添加的data 筛选掉
      },
      (err) => err
    );

    //针对每个new出来的实例 添加拦截器
    this.instance.interceptors.request.use(config.interceptor?.reqSuccess, config.interceptor?.reqFail);
    this.instance.interceptors.response.use(config.interceptor?.resSuccess, config.interceptor?.resFail);
  }

  // 主要封装request方法
  Request<T = any>(config: kaRequestConfig<T>) {
    // 单个方法请求拦截
    if (config.interceptor?.reqSuccess) {
      config = config.interceptor?.reqSuccess(config);
    }

    //单个请求是否需要加token
    if (config.isTokenRequire) {
      const token = localStorage.getItem('token');

      if (!token) return;
      config.headers.Authorization = `Bearer ${token}`;
    }

    return new Promise<T>((resolve, reject) => {
      // 难点  返回的res 类型是resquest <any,T>第二个T的类型
      this.instance
        .request<any, T>(config)
        .then((res) => {
          // 添加响应拦截
          if (config.interceptor?.resSuccess) {
            res = config.interceptor?.resSuccess(res);
          }

          resolve(res);
        })
        .catch((err) => reject(err));
    });
  }

  // 其他方法
  get<T = any>(config: kaRequestConfig<T>) {
    return this.Request({ ...config, method: 'GET' });
  }
  post<T = any>(config: kaRequestConfig<T>) {
    return this.Request({ data: {}, ...config, method: 'POST' });
  }
  delete<T = any>(config: kaRequestConfig<T>) {
    return this.Request({ ...config, method: 'DELETE' });
  }
  patch<T = any>(config: kaRequestConfig<T>) {
    return this.Request({ ...config, method: 'PATCH' });
  }
}

export default kaRequest;
